<template>
  <el-dialog v-model="displayCropModal" title="裁剪图片">
    <div class="modal-content">
      <!-- 图片裁切插件 -->
      <VuePictureCropper
        :boxStyle="{
          width: '100%',
          height: '100%',
          backgroundColor: '#f8f8f8',
          margin: 'auto',
        }"
        :img="pic"
        :options="{
          viewMode: 1,
          dragMode: 'move',
          aspectRatio: 1,
          cropBoxResizable: false,
        }"
        :presetMode="{
          mode: 'fixedSize',
          width: imgSize,
          height: imgSize,
        }"
      />
    </div>
    <template></template>
  </el-dialog>
</template>
<script>
  import VuePictureCropper, { cropper } from 'vue-picture-cropper'
  import { reactive, ref, onMounted, toRefs } from 'vue'
  export default {
    components: {
      VuePictureCropper,
    },
    setup(props, context) {
      // #region 变量
      const state = reactive({
        displayCropModal: false, // 弹框是否可见
        degreeNum: 0, // 旋转度数的次数
        onLoading: false, // 是否加载中
        imgSize: 300, // 图片固定宽高
      })
      // 图片显示
      const result = reactive({
        dataURL: '',
        blobURL: '',
      })
      const pic = ref('')
      // #endregion

      // #region 生命周期、监听、计算 函数
      onMounted(() => {})
      // #endregion

      // #region 页面操作方法
      // 生成：所选图片的裁剪画布
      const initCropInfo = (file) => {
        // 重置上一次的结果
        result.dataURL = ''
        result.blobURL = ''
        // 如果有多个裁剪框，也需要重置掉裁剪目标的值，避免使用同一张图片无法触发watch
        pic.value = ''
        if (!file) return
        // 转换为base64传给裁切组件
        const reader = new FileReader()
        reader.onload = () => {
          // 更新裁切弹窗的图片源
          pic.value = String(reader.result)
          // 获取加载出来的图片的最小宽或高
          let img = new Image()
          img.src = reader.result
          img.onload = function () {
            if (this.width <= this.height) {
              state.imgSize = this.width
            } else {
              state.imgSize = this.height
            }
          }
          // cropper.reset() // 重置默认的裁切区域
          // 显示裁切弹窗
          state.displayCropModal = true
          console.log('state.displayCropModal =' + state.displayCropModal)
        }
        reader.readAsDataURL(file)
      }
      // 操作：旋转
      const rorateImg = async (num) => {
        state.degreeNum += num
        // 设置旋转一次的幅度为 90°
        cropper.rotateTo((state.degreeNum % 4) * 90)
      }
      // 操作：裁剪框-确定
      const handleModalSure = async () => {
        if (state.onLoading) return
        state.onLoading = true
        // 获取生成的base64图片地址
        const base64 = cropper.getDataURL()
        // 获取生成的blob文件信息
        const blob = await cropper.getBlob()
        // 获取生成的file文件信息
        const file = await cropper.getFile({
          // fileName: '测试文件名，可不传'
        })
        // console.log({ base64, blob, file })
        // 把base64赋给结果展示区
        result.dataURL = base64
        try {
          result.blobURL = URL.createObjectURL(blob)
        } catch (e) {
          result.blobURL = ''
        }
        context.emit('handleModalSure', file)
        state.displayCropModal = false
        state.onLoading = false
      }
      // 操作：裁剪框-取消
      const handleModalCancel = () => {
        context.emit('handleModalCancel')
        state.displayCropModal = false
      }
      // #endregion

      return {
        ...toRefs(state),
        initCropInfo,
        result,
        pic,
        rorateImg,
        handleModalSure,
        handleModalCancel,
      }
    },
  }
</script>
